#ifndef ELEMENT_H
#define ELEMENT_H

#include <algorithm>
#include <vector>

#include <stdio.h>

#include "FEM/node.h"

/*template < typename _ObjectType_, typename ..._SpecificWrapper_> class Wrapper :
        public _ObjectType_, public _SpecificWrapper_...
{
public:
    Wrapper():_ObjectType_(){}
    Wrapper( const Wrapper &obj ):_ObjectType_(obj){}
};*/

/// \brief The Element class
template <int _nodesCount_, typename _NodeType_> class Element
{
public:
    _NodeType_ **nodes;

    Element()
    {
        nodes = new _NodeType_*[_nodesCount_];
    }

    /// \brief Copy constructor is deleted
    Element( const Element<_nodesCount_, _NodeType_> &el) = delete;
    Element operator = (const Element<_nodesCount_, _NodeType_> &el) = delete;

    ~Element()
    {
        delete[] nodes;
    }
};

/// \brief The FEMElement class
/// \f$ [K]^{(el)}[U]^{(el)}=[F]^{(el)} \f$.
template <int _nodesCount_, typename _NodeType_, typename _DimType_ = double> class FEMElement :
        public Element <_nodesCount_, _NodeType_>
{
    /// \brief Form function \f$ \phi=\left[N\right]\left\{U\right\} \f$.
    /// \param n Node to calculate \f$ \phi \f$.
    /// \return \f$ \phi \f$.
    virtual _DimType_ *formFunction(_NodeType_ *n) = 0;  //fi=[N]{U}

    /// \brief \f$ \left[K\right]^{(el)}=\int_{(el)} [B][D][B]d(el) \f$.
    _DimType_ *stiffnessMatrix;    //[K]

    /// \brief loadVector
    _DimType_ *loadVector;         //{F}

    /*/// \brief constraintMatrix
    _DimType_ *constraintMatrix;   //[D]*/
};

#endif // ELEMENT_H
